package com.wstuo.itsm.knowledge.service;


import com.wstuo.common.config.category.dto.CategoryDTO;
import com.wstuo.common.config.category.dto.CategoryTreeViewDTO;
import com.wstuo.common.config.category.entity.Category;
import com.wstuo.itsm.knowledge.dao.IKnowledgeCategoryDAO;
import com.wstuo.itsm.knowledge.entity.KnowledgeCategory;
import com.wstuo.common.exception.ApplicationException;

import org.apache.commons.beanutils.BeanUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * KnowledgeCategoryService Bean 2010.9.13
 * 
 * @author spring
 * 
 */
public class KnowledgeCategoryService implements IKnowledgeCategoryService {

	@Autowired
	private IKnowledgeCategoryDAO knowledgecategoryDAO;

	/**
	 * Check all KnowledgeCategoryTree
	 * 
	 * @return List<CategoryTreeViewDTO>
	 */
	@Transactional
	public List<CategoryTreeViewDTO> findKnowledgeCategoryTreeDtos(String name) {
		List<CategoryTreeViewDTO> dtos = new ArrayList<CategoryTreeViewDTO>();
		List<KnowledgeCategory> entities = knowledgecategoryDAO.findKnowledge(name);
		for (KnowledgeCategory entity : entities) {
			CategoryTreeViewDTO dto = new CategoryTreeViewDTO();
			KnowledgeCategoryService.entity2dto(entity, dto);
			dtos.add(dto);
		}

		return dtos;
	}

	/**
	 * Save KnowledgeCategory
	 * 
	 * @param dto
	 */
	@Transactional
	public void saveKnowledgeCategory(CategoryDTO dto) {
		KnowledgeCategory entity = new KnowledgeCategory();

		KnowledgeCategoryService.dto2entity(dto, entity);

		if (dto.getParentNo() != null) {
			KnowledgeCategory parent = knowledgecategoryDAO.findById(dto.getParentNo());

			entity.setParent(parent);
		}

		knowledgecategoryDAO.save(entity);
		dto.setCno(entity.getCno());
	}

	/**
	 * Remove KnowledgeCategory
	 * 
	 * @param kno
	 */
	@Transactional
	public void removeKnowledgeCategory(Long kno) {
		knowledgecategoryDAO.delete(knowledgecategoryDAO.findById(kno));
	}

	/**
	 * Update KnowledgeCategory
	 * 
	 * @param dto
	 */
	@Transactional
	public void updateKnowledgeCategory(CategoryDTO dto) {
		KnowledgeCategory entity = knowledgecategoryDAO.findById(dto.getCno());

		if (dto.getCname() != null) {
			entity.setCname(dto.getCname());
		}

		if (dto.getDescription() != null) {
			entity.setDescription(dto.getDescription());
		}
	}

	/**
	 * Change KnowledgeCategory
	 * 
	 * @param dto
	 */
	@Transactional
	public void changeKnowledgeCategory(CategoryDTO dto) {
		KnowledgeCategory entity = knowledgecategoryDAO.findById(dto.getCno());
		KnowledgeCategory parent = knowledgecategoryDAO.findById(dto.getParentNo());

		entity.setParent(parent);
	}

	/**
	 * find KnowledgeCategory
	 * 
	 * @param cno
	 */
	@SuppressWarnings("static-access")
	@Transactional
	public CategoryDTO findKnowledgeCategoryById(long cno) {
		CategoryDTO dto = new CategoryDTO();
		KnowledgeCategory entity = knowledgecategoryDAO.findById(cno);
		this.entity2dto(entity, dto);
		if (dto != null && entity.getParent() != null) {
			dto.setParentNo(entity.getParent().getCno());
		}
		return dto;

	}

	/********************************* Conversion ****************************************/

	/**
	 * dto2entity Method
	 * 
	 * @param dto
	 * @param entity
	 */
	private static void dto2entity(CategoryDTO dto, KnowledgeCategory entity) {
		try {
			BeanUtils.copyProperties(entity, dto);
		} catch (Exception ex) {
			throw new ApplicationException(ex);
		}
	}

	/**
	 * entity2dto Method
	 * 
	 * @param entity
	 * @param dto
	 */
	private static void entity2dto(KnowledgeCategory entity, CategoryDTO dto) {
		try {
			BeanUtils.copyProperties(dto, entity);
		} catch (Exception ex) {
			throw new ApplicationException(ex);
		}
	}

	/**
	 * entity2dto Method
	 * 
	 * @param entity
	 * @param dto
	 */
	private static void entity2dto(Category entity, CategoryTreeViewDTO dto) {
		try {
			dto.setData(entity.getCname());
			dto.getAttr().put("cno", "" + entity.getCno());
			dto.getAttr().put("cname", entity.getCname());
			dto.getAttr().put("description", entity.getDescription());
			if (entity.getChildren() != null && !entity.getChildren().isEmpty()) {
				dto.setState("close");
				for (Category ctg : entity.getChildren()) {
					CategoryTreeViewDTO regDTO = new CategoryTreeViewDTO();
					KnowledgeCategoryService.entity2dto(ctg, regDTO);
					dto.getChildren().add(regDTO);
				}
			}
		} catch (Exception ex) {
			throw new ApplicationException("Exception caused while converting Entity into DTO: " + ex.getMessage(), ex);
		}
	}
}
